import React, {
  memo,
  useState,
  useMemo,
  useRef,
  useEffect,
  useCallback,
  // useCallback,
} from 'react';
import './Slider.css';
import PropTypes from 'prop-types';
import leftPad from 'left-pad';
import useWinSize from '../common/useWinSize';
import { useThrottle } from '../common/useThrottle';

const Slider = memo(function Slider(props) {
  const {
    title,
    currentStartHours,
    currentEndHours,
    onStartChanged,
    onEndChanged,
  } = props;
  //当前的开始节点
  const startHandle = useRef();
  //当前的结束节点
  const endHandle = useRef();
  //上一次的开始节点
  const lastStartX = useRef();
  //上一次的结束节点
  const lastEndX = useRef();
  //可滑动的宽度
  const range = useRef();
  const rangeWidth = useRef();

  const winSize = useWinSize();
  //在组建第一次渲染的时候才会去初始化useState中的函数
  const [start, setStart] = useState(() => (currentStartHours / 24) * 100); //0
  const [end, setEnd] = useState(() => (currentEndHours / 24) * 100); //24

  //记录上一次传入的props的值
  const prevCurrentStartHours = useRef(currentStartHours);
  const prevCurrentEndHours = useRef(currentEndHours);

  //如果当前传入的props属性中的currentStartHours与上一次不一致,则将当前的useState(只渲染一次)中的start更新为本次传进来的值
  if (prevCurrentStartHours.current !== currentStartHours) {
    setStart((currentStartHours / 24) * 100);
    //将当前传入的currentStartHours记录
    prevCurrentStartHours.current = currentStartHours;
  }
  if (prevCurrentEndHours.current !== currentEndHours) {
    setEnd((currentEndHours / 24) * 100);
    //将当前传入的currentStartHours记录
    prevCurrentEndHours.current = currentEndHours;
  }
  //

  //设置上下限  转化为百分比[0,100]
  const startPercent = useMemo(() => {
    if (start > 100) {
      return 100;
    }
    if (start > end) {
      return end;
    }
    if (start < 0) {
      return 0;
    }
    return start;
  }, [start, end]);
  const endPercent = useMemo(() => {
    if (end > 100) {
      return 100;
    }
    if (start > end) {
      return start;
    }
    if (end < 0) {
      return 0;
    }
    return end;
  }, [start, end]);

  // console.log(`start:${start},end:${end}`);
  //转化为 0-24数字
  const startHour = useMemo(() => {
    return Math.round((startPercent * 24) / 100);
  }, [startPercent]);
  const endHour = useMemo(() => {
    return Math.round((endPercent * 24) / 100);
  }, [endPercent]);
  //转化为 文本
  const startText = useMemo(() => {
    return leftPad(startHour, 2, '0') + ':00';
  }, [startHour]);
  const endText = useMemo(() => {
    return leftPad(endHour, 2, '0') + ':00';
  }, [endHour]);

  const onStartTouchBegin = useThrottle(function (e) {
    const touch = e.targetTouches[0];
    //获取当前触摸的X坐标位置
    lastStartX.current = touch.pageX;
  }, 50);

  const onStartTouchMove = useThrottle(function (e) {
    const touch = e.targetTouches[0];
    const distance = touch.pageX - lastStartX.current;
    lastStartX.current = touch.pageX;
    setStart((start) => {
      console.log(start);
      let res = start + (distance / rangeWidth.current) * 100;
      return res > 100 ? 100 : res < 0 ? 0 : res;
    });
  }, 50);

  function onEndTouchBegin(e) {
    const touch = e.targetTouches[0];
    lastEndX.current = touch.pageX;
  }

  function onEndTouchMove(e) {
    const touch = e.targetTouches[0];
    const distance = touch.pageX - lastEndX.current;
    lastEndX.current = touch.pageX;
    setEnd((start) => {
      let res = start + (distance / rangeWidth.current) * 100;
      return res > 100 ? 100 : res < 0 ? 0 : res;
    });
  }

  // 告知父组件 滑块变化了
  useEffect(() => {
    onStartChanged(startHour);
  }, [onStartChanged, startHour]);
  useEffect(() => {
    onEndChanged(endHour);
  }, [endHour, onEndChanged]);

  //当窗体发生变化的时候,重新计算range的宽度
  useEffect(() => {
    rangeWidth.current = parseFloat(
      window.getComputedStyle(range.current).width
    );
  }, [winSize.width]);
  //因为每一次渲染 都有操作dom 会有dom的重构,所以需要每一次副作用渲染的时候重新绑定事件;
  //因为重渲染会删除事件绑定,所以不用担心事件泄露
  useEffect(() => {
    const startDom = startHandle.current;
    const endDom = endHandle.current;
    //对dom节点进行事件绑定 ,useRef并不是dom的节点,而是useRef.current
    startDom.addEventListener('touchstart', onStartTouchBegin, false);
    startDom.addEventListener('touchmove', onStartTouchMove, false);
    endDom.addEventListener('touchstart', onEndTouchBegin, false);
    endDom.addEventListener('touchmove', onEndTouchMove, false);
    return () => {
      startDom.removeEventListener('touchstart', onStartTouchBegin, false);
      startDom.removeEventListener('touchmove', onStartTouchMove, false);
      endDom.removeEventListener('touchstart', onEndTouchBegin, false);
      endDom.removeEventListener('touchmove', onEndTouchMove, false);
    };
  });

  return (
    <div className="option">
      <h3>{title}</h3>
      <div className="range-slider">
        {/* 底色线 */}
        <div className="slider" ref={range}>
          {/* 亮色线 */}
          <div
            className="slider-range"
            style={{
              left: startPercent + '%',
              width: endPercent - startPercent + '%',
            }}
          ></div>
          <i
            ref={startHandle}
            className="slider-handle"
            style={{ left: startPercent + '%' }}
          >
            <span>{startText}</span>
          </i>
          <i
            ref={endHandle}
            className="slider-handle"
            style={{
              left: endPercent + '%',
            }}
          >
            <span>{endText}</span>
          </i>
        </div>
      </div>
    </div>
  );
});

Slider.propTypes = {
  title: PropTypes.string.isRequired,
  currentStartHours: PropTypes.number.isRequired,
  currentEndHours: PropTypes.number.isRequired,
  onStartChanged: PropTypes.func.isRequired,
  onEndChanged: PropTypes.func.isRequired,
};
export default Slider;
